﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.ComponentModel;
using ProxyViewModel;
namespace AutoViewModel.Tests {
	[TestClass]
	public class TestAllPropertyTypes {
		[TestMethod]
		public void TestIntegerProperty() {
			CheckObservability<int>(155);
		}

		[TestMethod]
		public void TestStringProperty() {
			CheckObservability<string>("awesomevalue");
		}

		[TestMethod]
		public void TestBoolProperty() {
			CheckObservability<bool>(true);
		}

		[TestMethod]
		public void TestByteProperty() {
			CheckObservability<byte>(4);
		}

		[TestMethod]
		public void TestSbyteProperty() {
			CheckObservability<sbyte>(67);
		}

		[TestMethod]
		public void TestCharProperty() {
			CheckObservability<char>('2');
		}

		[TestMethod]
		public void TestDecimalProperty() {
			CheckObservability<decimal>(234);
		}

		[TestMethod]
		public void TestDoubleProperty() {
			CheckObservability<double>(23);
		}

		[TestMethod]
		public void TestFloatProperty() {
			CheckObservability<double>(23);
		}

		[TestMethod]
		public void TestUintProperty() {
			CheckObservability<uint>(224);
		}

		[TestMethod]
		public void TestLongProperty() {
			CheckObservability<long>(2244234234);
		}

		[TestMethod]
		public void TestUlongProperty() {
			CheckObservability<long>(22442342343);
		}

		[TestMethod]
		public void TestObjectProperty() {
			CheckObservability<object>("does not metter what");
		}

		[TestMethod]
		public void TestShortProperty() {
			CheckObservability<short>(6555);
		}

		[TestMethod]
		public void TestUshortProperty() {
			CheckObservability<ushort>(6554);
		}

		[TestMethod]
		public void TestCustomObject() {
			ViewModelMock obj1 = new ViewModelMock();
			obj1.MyProperty1 = "myprop1";
			obj1.MyProperty2 = "myprop2";
			obj1.IntsCollection = new List<int> { 1, 2, 34, 6, 34, 65 };

			GenericTypeViewModelMock<ViewModelMock> viewModel = CheckObservability<ViewModelMock>(obj1);

			Assert.AreEqual(viewModel.MyProperty.MyProperty1, obj1.MyProperty1);
			Assert.AreEqual(viewModel.MyProperty.MyProperty2, obj1.MyProperty2);

			ViewModelMock obj2 = new ViewModelMock();

			obj2.MyProperty1 = "myprop2";
			obj2.MyProperty2 = "myprop2";
			obj2.IntsCollection = new List<int> { 2, 4, 5 };

			bool propertyChangedCalled = false;

			viewModel.PropertyChanged += new PropertyChangedEventHandler((s, e) => {
				if (e.PropertyName == "MyProperty") {
					propertyChangedCalled = true;
				}
			});

			viewModel.MyProperty = obj2;

			Assert.AreEqual(viewModel.MyProperty, obj2);
			Assert.AreEqual(viewModel.MyProperty.MyProperty1, obj2.MyProperty1);
			Assert.AreEqual(viewModel.MyProperty.MyProperty2, obj2.MyProperty2);
			Assert.AreEqual(viewModel.MyProperty.IntsCollection.Count, 3);
			Assert.IsTrue(propertyChangedCalled);
		}

		public GenericTypeViewModelMock<PropertyType> CheckObservability<PropertyType>(PropertyType value) {
			GenericTypeViewModelMock<PropertyType> observableViewModel = ProxyViewModelFactory.CreateProxyViewModel<GenericTypeViewModelMock<PropertyType>>();
			bool notificationChangedWasCalled = false;
			observableViewModel.PropertyChanged += new PropertyChangedEventHandler((s, e) => {
				if (e.PropertyName == "MyProperty") {
					notificationChangedWasCalled = true;
				}
			});
			observableViewModel.MyProperty = value;
			Assert.AreEqual(observableViewModel.MyProperty, value);
			Assert.IsTrue(notificationChangedWasCalled);

			return observableViewModel;
		}
	}
}
